﻿
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Common
{
    public class FtpHelper
    {
        private static ListBox list_Info;
        private static ListBox list_Error;
        /// <summary>  
        /// 上传文件到FTP服务器(断点续传)  
        /// </summary>  
        /// <param name="localFullPath">本地文件全路径名称</param>  
        /// <param name="remoteFilepath">远程文件所在文件夹路径</param>  
        /// <param name="listbox"></param>
        /// <returns></returns>  
        public static bool FtpUploadBroken(string localFullPath, string remoteFilepath, ListBox listbox, ListBox listbox2, FtpArg args)
        {
            list_Info = listbox;
            list_Error = listbox2;
            if (remoteFilepath == null)
            {
                remoteFilepath = "";
            }
            string newFileName = string.Empty;
            bool success = true;
            FileInfo fileInf = new FileInfo(localFullPath);
            long allbye = (long)fileInf.Length;
            if (fileInf.Name.IndexOf("#") == -1)
            {
                newFileName = RemoveSpaces(fileInf.Name);
            }
            else
            {
                newFileName = fileInf.Name.Replace("#", "＃");
                newFileName = RemoveSpaces(newFileName);
            }
            long startfilesize = GetFileSize(newFileName, remoteFilepath, args);
            if (startfilesize >= allbye)
            {
                return false;
            }
            long startbye = startfilesize;
            string uri;
            if (remoteFilepath.Length == 0)
            {
                uri = string.Format("ftp://{0}/{1}", args.FtpServerIP, newFileName);
            }
            else
            {
                uri = string.Format("ftp://{0}/{1}/{2}", args.FtpServerIP, remoteFilepath, newFileName);
            }
            FtpWebRequest reqFTP;
            reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
            reqFTP.Credentials = new NetworkCredential(args.FtpUserID, args.FtpPassword);
            reqFTP.KeepAlive = false;
            reqFTP.Method = WebRequestMethods.Ftp.AppendFile;
            reqFTP.UseBinary = true;
            reqFTP.ContentLength = fileInf.Length;
            int bufferLength = 2048;
            byte[] buffer = new byte[bufferLength];
            FileStream fs = fileInf.Open(FileMode.Open, FileAccess.ReadWrite);
            Stream strm = null;
            try
            {
                strm = reqFTP.GetRequestStream();
                fs.Seek(startfilesize, 0);
                int contentLen = 0;
                do
                {
                    contentLen = fs.Read(buffer, 0, bufferLength);
                    strm.Write(buffer, 0, contentLen);
                    startbye += contentLen;
                    if (startbye / 1024 % 200 == 0)//200K显示一个进度
                        ShowMsg.showMsg(list_Info, string.Format("{0} is transfering...{1}KB/{2}KB", newFileName, (int)startbye / 1024, (int)allbye / 1024));
                }
                while (contentLen == bufferLength);
                ShowMsg.showMsg(list_Info, string.Format("{0} is transfering...{1}KB/{2}KB, ok!", newFileName, (int)allbye / 1024, (int)allbye / 1024));
                strm.Close();
                fs.Close();
            }
            catch (Exception ex)
            {
                success = false;
                ShowMsg.showMsg(list_Error, ex.Message, 2);
                throw;
            }
            finally
            {
                if (fs != null)
                {
                    fs.Close();
                }
                if (strm != null)
                {
                    strm.Close();
                }
            }
            return success;
        }

        /// <summary>
        /// 从FTP服务器下载文件
        /// </summary>
        /// <param name="remoteFileName"></param>
        /// <param name="localFileName"></param>
        /// <param name="ifCredential"></param>
        /// <param name="size"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static bool FtpDownloadBroken(string remoteFileName, string remotePath, string localFileName, bool ifCredential, long size, FtpArg args)
        {
            FtpWebRequest reqFTP, ftpsize;
            Stream ftpStream = null;
            FtpWebResponse response = null;
            FileStream outputStream = null;
            try
            {
                outputStream = new FileStream(localFileName, FileMode.Append);
                if (args.FtpServerIP == null || args.FtpServerIP.Trim().Length == 0)
                {
                    throw new Exception("ftp下载目标服务器地址未设置！");
                }
                Uri uri = new Uri("ftp://" + args.FtpServerIP + "/" + remotePath + "/" + remoteFileName);
                ftpsize = (FtpWebRequest)FtpWebRequest.Create(uri);
                ftpsize.UseBinary = true;
                ftpsize.ContentOffset = size;
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
                reqFTP.UseBinary = true;
                reqFTP.KeepAlive = false;
                reqFTP.ContentOffset = size;
                if (ifCredential)//使用用户身份认证  
                {
                    ftpsize.Credentials = new NetworkCredential(args.FtpUserID, args.FtpPassword);
                    reqFTP.Credentials = new NetworkCredential(args.FtpUserID, args.FtpPassword);
                }
                ftpsize.Method = WebRequestMethods.Ftp.GetFileSize;
                FtpWebResponse re = (FtpWebResponse)ftpsize.GetResponse();
                long totalBytes = re.ContentLength;
                re.Close();

                reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
                response = (FtpWebResponse)reqFTP.GetResponse();
                ftpStream = response.GetResponseStream();
               
                long totalDownloadedByte = 0;
                int bufferSize = 2048;
                int readCount;
                byte[] buffer = new byte[bufferSize];
                readCount = ftpStream.Read(buffer, 0, bufferSize);
                
                while (readCount > 0)
                {
                    totalDownloadedByte = readCount + totalDownloadedByte;
                    outputStream.Write(buffer, 0, readCount);                   
                    readCount = ftpStream.Read(buffer, 0, bufferSize);
                    string info = string.Format("downloading...{0}KB", totalDownloadedByte / 1024);
                    ShowMsg.showMsg(list_Info, info);
                }
                ftpStream.Close();
                outputStream.Close();
                response.Close();
                return true;
            }
            catch (Exception)
            {
                return false;
                throw;
            }
            finally
            {
                if (ftpStream != null)
                {
                    ftpStream.Close();
                }
                if (outputStream != null)
                {
                    outputStream.Close();
                }
                if (response != null)
                {
                    response.Close();
                }
            }
        }

        //获取ftp上面的文件
        public static string GetFile(string remotePath, string searchFile, FtpArg args, ListBox listbox, ListBox listbox2)
        {
            string downloadUpgradeFile = "";
            list_Info = listbox;
            list_Error = listbox2;
            FtpWebRequest request;
            try
            {
                request = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + args.FtpServerIP + "/" + remotePath));
                request.UseBinary = true;
                request.Credentials = new NetworkCredential(args.FtpUserID, args.FtpPassword);//设置用户名和密码
                request.Method = WebRequestMethods.Ftp.ListDirectory;
                request.UseBinary = true;
                WebResponse response = request.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream());
                string line = reader.ReadLine();
                bool flag = false;
                while (line != null)
                {
                    if (line.Contains(searchFile))
                    {
                        downloadUpgradeFile = line;
                        ShowMsg.showMsg(list_Info, "发现目标文件，开始下载...");
                        flag = true;
                        break;
                    }
                    
                    line = reader.ReadLine();
                }
                if(!flag)
                    ShowMsg.showMsg(list_Info, "当前版本为最新版本");
                reader.Close();
                response.Close();                
            }
            catch (Exception ex)
            {
                ShowMsg.showMsg(list_Error, "获取ftp上面的文件和文件夹：" + ex.Message);
                return "-1";
            }
            return downloadUpgradeFile;
        }

        /// <summary>  
        /// 去除空格  
        /// </summary>  
        /// <param name="str"></param>  
        /// <returns></returns>  
        private static string RemoveSpaces(string str)
        {
            string a = "";
            CharEnumerator CEnumerator = str.GetEnumerator();
            while (CEnumerator.MoveNext())
            {
                byte[] array = new byte[1];
                array = System.Text.Encoding.ASCII.GetBytes(CEnumerator.Current.ToString());
                int asciicode = (short)(array[0]);
                if (asciicode != 32)
                {
                    a += CEnumerator.Current.ToString();
                }
            }
            string sdate = System.DateTime.Now.Year.ToString() + System.DateTime.Now.Month.ToString() + System.DateTime.Now.Day.ToString() + System.DateTime.Now.Hour.ToString()
                + System.DateTime.Now.Minute.ToString() + System.DateTime.Now.Second.ToString() + System.DateTime.Now.Millisecond.ToString();
            return a.Split('.')[a.Split('.').Length - 2] + "." + a.Split('.')[a.Split('.').Length - 1];
        }
        /// <summary>
        /// 获取已上传的文件大小
        /// </summary>
        /// <param name="filename">文件名称</param>
        /// <param name="remoteFilepath">服务器文件路径</param>
        /// <param name="FtpArg">ftp参数，ip,登录名，密码</param>
        /// <returns></returns>
        public static long GetFileSize(string filename, string remoteFilepath, FtpArg args)
        {
            long filesize = 0;
            try
            {
                FtpWebRequest reqFTP;
                FileInfo fi = new FileInfo(filename);
                string uri;
                if (remoteFilepath.Length == 0)
                {
                    uri = "ftp://" + args.FtpServerIP + "/" + fi.Name;
                }
                else
                {
                    uri = "ftp://" + args.FtpServerIP + "/" + remoteFilepath + "/" + fi.Name;
                }
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(uri);
                reqFTP.KeepAlive = false;
                reqFTP.UseBinary = true;
                reqFTP.Credentials = new NetworkCredential(args.FtpUserID, args.FtpPassword);//用户，密码  
                reqFTP.Method = WebRequestMethods.Ftp.GetFileSize;
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                filesize = response.ContentLength;
                return filesize;
            }
            catch
            {
                return 0;
            }
        }
    }
}
